package com.wu.ssm.spring.ioc;

import com.wu.ssm.spring.InstanceFactory;
import com.wu.ssm.spring.annotion.MyBean;
import com.wu.ssm.spring.annotion.MyController;
import com.wu.ssm.spring.annotion.MyService;
import com.wu.ssm.spring.core.ClassScanner;
import com.wu.ssm.spring.utils.ClassUtil;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by wzf on 2018/11/28/028.
 */
public class ClassHelper {

    /**
     * 获取 ClassScanner
     */
    private static final ClassScanner classScanner = InstanceFactory.getClassScanner();

    /**
     * 获取基础包名
     */
    private static final String basePackage = "com.wu.ssm";

    /**
     * (集合)用于存放所有获取的类
     */
    private static final Set<Class<?>> CLASS_SET;

    static {
        CLASS_SET = ClassUtil.getClassSet("com.wu.ssm");
    }


    /**
     * 获取所有类
     */
    public static Set<Class<?>> getClassSet(){

        return CLASS_SET;
    }

    /**
     * 获取指定包下的所有Controller类
     */
    public static Set<Class<?>> getControllerClassSet(){
        Set<Class<?>> classSet = new HashSet<>();
        for (Class<?> clazz: CLASS_SET
             ) {
            if(clazz.isAnnotationPresent(MyController.class)){
                classSet.add(clazz);
            }
        }
        return classSet;
    }

    /**
     * 获取指定包下的所有service类
     */
    public static Set<Class<?>> getServiceClassSet(){
        Set<Class<?>> classSet = new HashSet<>();
        for (Class<?> clazz: CLASS_SET
        ) {
            if(clazz.isAnnotationPresent(MyService.class)){
                classSet.add(clazz);
            }
        }
        return classSet;
    }
    /**
     * 获取指定包下的所有bean类
     */
    public static Set<Class<?>> getBeanClassSet(){
        Set<Class<?>> classSet = new HashSet<>();
        for (Class<?> clazz: CLASS_SET
        ) {
            if(clazz.isAnnotationPresent(MyBean.class)){
                classSet.add(clazz);
            }
        }
        return classSet;
    }

    /**
     * 获取指定包下的所有bean,Controller,service类
     */
    public static Set<Class<?>> getAllBeanClassSet(){
        Set<Class<?>> classSet = new HashSet<>();
        classSet.addAll(getControllerClassSet());
        classSet.addAll(getServiceClassSet());
        classSet.addAll(getBeanClassSet());
        return classSet;
    }

    /**
     * 获取包名下某父类（或接口）的所有子类（或实现类）
     * class1.isAssignableFrom(class2) 判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同，或是否是其超类或超接口。
     * 如果是则返回 true；否则返回 false。如果该 Class 表示一个基本类型，且指定的 Class 参数正是该 Class 对象，则该方法返回 true；否则返回 false
     */
    public static Set<Class<?>> getClassesSetBySuper(Class<?> superClazz){
        Set<Class<?>> classSet = new HashSet<>();
        for (Class<?> clazz: CLASS_SET
        ) {
            if(superClazz.isAssignableFrom(clazz) && !superClazz.equals(clazz)){
                classSet.add(clazz);
            }
        }
        return classSet;
    }

    /**
     * 获取指定包下的带有某注解的所有类
     */
    public static Set<Class<?>> getClassSetByAnnotatin(Class<? extends Annotation> annotationClazz){
        Set<Class<?>> classSet = new HashSet<>();
        for (Class<?> clazz: CLASS_SET
        ) {
            if(clazz.isAnnotationPresent(annotationClazz)){
                classSet.add(clazz);
            }
        }
        return classSet;
    }

    /**
     * 获取某父类（或接口）的所有子类（或实现类）
     */
    public static Set<Class<?>> getClassSetBySuper(Class<?> superClazz){
        Set<Class<?>> classSet = new HashSet<>();

        for (Class<?> clazz: CLASS_SET
        ) {
            if (superClazz.isAssignableFrom(clazz) && !superClazz.equals(clazz)){
                classSet.add(clazz);
            }
        }
        return classSet;
    }
    /**
     * 获取某父类（或接口）的所有子类（或实现类）
     */
    public static List<Class<?>> getClassListBySuper(Class<?> superClass) {
        return classScanner.getClassListBySuper(basePackage, superClass);
    }


    /**
     * 获取包下所有带某注解的类
     */
    public static Set<Class<?>> getClassSetByAnnotion(Class<? extends Annotation> annotitionClass){
        Set<Class<?>> setClass = new HashSet<>();
        for (Class<?> clazz :CLASS_SET
        ) {
            if (clazz.isAnnotationPresent(annotitionClass)){
                setClass.add(clazz);
            }
        }
        return setClass;
    }

    /**
     * 获取包下所有带某注解的类
     */
    public static List<Class<?>> getClassListByAnnotation(Class<? extends Annotation> annotitionClass){
        return classScanner.getClassListByAnnotation(basePackage, annotitionClass);
    }
    /**
     * 获取包下所有方法中带有某注解的类
     */
    public static List<Class<?>> getClassListByMethodAnnotion(Class<? extends Annotation> annotitionClass){
        List<Class<?>> classList = new ArrayList<>();
        for (Class<?> clazz :CLASS_SET
        ) {
            Method [] methods = clazz.getDeclaredMethods();
            for (Method method:methods
                 ) {
                if (method.isAnnotationPresent(annotitionClass)){
                    classList.add(clazz);
                }
            }
        }
        return classList;
    }
}
